package com.linshidream.intrachat.simplenio.pipeline.context;

import java.nio.ByteBuffer;
import java.nio.channels.Selector;
import java.nio.channels.SocketChannel;
import java.util.LinkedList;
import java.util.Queue;

/**
 * Created on 2025/8/19 18:27
 *
 * @author linshidream
 * @version 1.0.0
 * @description 通道持有对象，负责触发事件、管理 Socketchannel
 * <p>
 * <>入站：channel表示责任链的第一环，往后传递</>
 * <>出站：channel表示责任链的最后一环，往前传递</>
 */

public class MiniChannel {

    private final SocketChannel socketChannel;

    private final Selector selector;

    /**
     * 累积的 buffer，用于读数据缓冲
     */
    private final ByteBuffer inBuffer = ByteBuffer.allocate(1024 * 8);

    /**
     * 写数据缓冲
     */
    private final Queue<ByteBuffer> outQueue = new LinkedList<>();

    private final MiniChannelPipeline pipeline;

    private Boolean isActive = Boolean.FALSE;

    public MiniChannel(SocketChannel socketChannel, Selector selector) {
        this.socketChannel = socketChannel;
        this.selector = selector;

        this.pipeline = new MiniChannelPipeline(this);
    }

    public MiniChannelPipeline pipeline() {
        return pipeline;
    }

    public Selector selector() {
        return selector;
    }

    public SocketChannel socketChannel() {
        return socketChannel;
    }

    public ByteBuffer accumulate(ByteBuffer buffer) {
        // 当前连接通道下的 缓冲区未读数据 + buffer未读数据
        return this.inBuffer.put(buffer);
    }

    public ByteBuffer inBuffer() {
        return inBuffer;
    }

    public Queue<ByteBuffer> outQueue() {
        return outQueue;
    }

    public void setInAvtive(){
        this.isActive = Boolean.FALSE;
    }

    public Boolean isActive() {
        return this.isActive;
    }

    /**
     * 事件触发入口，从第一个处理器开始
     */

    public void active() {
         // 将激活状态改为已激活
        this.isActive = Boolean.TRUE;

        pipeline.fireChannelActive(0);
    }

    public void inactive() {
        this.isActive = Boolean.FALSE;

        pipeline.fireChannelInactive(0);
    }

    public void receive(Object msg) {
        pipeline.fireChannelRead(msg, 0);
    }

    public void exception(Throwable t) {
        pipeline.fireExceptionCaught(t, 0);
    }


    /**
     * 事件触发出口, 从最后一个处理器开始
     */
    public void write(Object msg) {
        pipeline.fireChannelWrite(msg, pipeline.contextsSize() - 1);
    }

}
